import Objects from "../../utils/objects";
import * as Cesium from "cesium";
//引入echarts组件
import echarts from "echarts/lib/echarts";
import "echarts/lib/chart/bar";
import "echarts/lib/chart/line";
import "echarts/lib/chart/pie";
import "echarts/lib/component/tooltip";
import "echarts/lib/component/legend";
import "echarts/lib/component/markPoint";
import "echarts/lib/component/markLine";
import "echarts/lib/component/graphic";

/**
 * ProfileAnalysis 剖面分析
 * @param viewer Cesium.Viewer
 * @constructor ProfileAnalysis
 */
function ProfileAnalysis(viewer) {
    this._viewer = viewer;
    this._viewer.terrainProvider1 = viewer.terrainProvider;

    ProfileAnalysis._HANDLER = new Cesium.ScreenSpaceEventHandler(this._viewer.scene.canvas);

    this._myChart = null;
    this._linePositions = [];
    this._dom1 = document.getElementById("drawprofile"); // 绘图对象


    this.objtoremove = [];

    this._stopped = false;
    //this._startFly();
    ProfileAnalysis.MEASURERS.push(this);
}

ProfileAnalysis._HANDLER = null;
ProfileAnalysis.MEASURERS = [];

Object.defineProperties(ProfileAnalysis.prototype, {
    stopped: {
        get: function() {
            return this._stopped;
        }
    }
});

ProfileAnalysis.newInstance = function(viewer) {
    return new ProfileAnalysis(viewer);
};

ProfileAnalysis.lastMeasurer = function() {
    if (ProfileAnalysis.MEASURERS.length === 0) {
        throw new Error("尚未拥有实例！！！");
    }

    return ProfileAnalysis.MEASURERS[ProfileAnalysis.MEASURERS.length - 1];
};

ProfileAnalysis.prototype._startFly = function() {
    let that = this;
    that._viewer.camera.setView({
        destination: Cesium.Cartesian3.fromDegrees(128.055, 42.046, 8000),
        orientation: new Cesium.HeadingPitchRoll(Cesium.Math.toRadians(0), Cesium.Math.toRadians(-90), Cesium.Math.toRadians(0))
    });
};

ProfileAnalysis.prototype.start = function() {
    //this._viewer.entities.removeAll();
    for(var i = 0; i != this.objtoremove.length; ++i)
    {
        this._viewer.entities.remove(this.objtoremove[i]);
    }
    this.objtoremove = [];
    this._linePositions = [];
    this.drawLine();
    ProfileAnalysis._HANDLER.setInputAction(evt => {
        let position = this._getCartesian3FromPosition(evt.position);
        this._linePositions.push(position);
        this.addPoint(position);
        
    }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
    ProfileAnalysis._HANDLER.setInputAction(evt => {
        ProfileAnalysis._HANDLER.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
        ProfileAnalysis._HANDLER.removeInputAction(Cesium.ScreenSpaceEventType.RIGHT_CLICK);
        this.profileAnalyse();
    }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);
};
function buildModel(model) {
    for (let i in model) {
        if (model[i] != null) {
            if (model[i].constructor === Object) {
                buildModel(model[i]);
            } else {
                console.log(i + "\t" + model[i]);
            }
        }
    }
}
ProfileAnalysis.prototype.profileAnalyse = function() {
    // Calculate the lengths along the line positions
    let accum_lengths = [];
    for(let i = 0; i < this._linePositions.length - 1; ++i)
    {
        let length = Cesium.Cartesian3.distance(this._linePositions[i], this._linePositions[i + 1]);
        if(accum_lengths.length === 0) {
            accum_lengths.push(length);
        }
        else {
            accum_lengths.push(accum_lengths[accum_lengths.length - 1] + length);
        }

    }
    let count = 100;
    let totalLength = accum_lengths[accum_lengths.length - 1];
    let step = totalLength / count;
    let walkLength = 0.0;
    let walkSegment = 0;
    let interpolatePoints = [];
    while(walkLength <= totalLength)
    {
        // Find the segment which the walk length sits
        while(walkLength >= accum_lengths[walkSegment])
        {
            ++walkSegment;
        }
        let residualLengthInSegment = 0;
        if(walkSegment === 0)
        {
            residualLengthInSegment = walkLength;
        }
        else
        {
            residualLengthInSegment = walkLength - accum_lengths[walkSegment - 1];
        }

        if(residualLengthInSegment === 0.0)
        {
            interpolatePoints.push(Cesium.Cartographic.fromCartesian(this._linePositions[walkSegment]));
        }
        else
        {
            let segmentLength = 0;
            if(walkSegment === 0)
            {
                segmentLength = accum_lengths[walkSegment];
            }
            else
            {
                segmentLength = accum_lengths[walkSegment] - accum_lengths[walkSegment - 1];
            }
            let point = Cesium.Cartesian3.lerp(this._linePositions[walkSegment], this._linePositions[walkSegment + 1],residualLengthInSegment / segmentLength, new Cesium.Cartesian3());
            interpolatePoints.push(Cesium.Cartographic.fromCartesian(point));
        }

        walkLength += step;
    }

    if(walkLength > totalLength)
    {
        interpolatePoints.push(Cesium.Cartographic.fromCartesian(this._linePositions[this._linePositions.length - 1]));
    }

    // 异步使用最精确的地形采样获取地形高度
    let promise = Cesium.sampleTerrainMostDetailed(this._viewer.terrainProvider1, interpolatePoints);
    let that = this;
    Cesium.when(promise, function(updatedPositions) {
        // 处理返回的数据
        let height = [];
        let distance = [];
        let j = 0;
        for (let i = 0; i < updatedPositions.length - 1; i++) {
            height.push(updatedPositions[i].height); // 取得高程值

            let a = Cesium.Cartographic.toCartesian(updatedPositions[i]).x - Cesium.Cartographic.toCartesian(updatedPositions[i + 1]).x;
            let b = Cesium.Cartographic.toCartesian(updatedPositions[i]).y - Cesium.Cartographic.toCartesian(updatedPositions[i + 1]).y;

            j += Math.sqrt(Math.pow(a, 2) + Math.pow(b, 2));
            distance.push(j);
        }
        height.push(updatedPositions[updatedPositions.length - 1].height);

        distance.unshift(0); //起点位置长度为0

        function toTwoDimension(arr1, arr2) {
            let arr = [];
            for (let i = 0; i < arr1.length; i++) {
                arr.push([arr1[i], arr2[i]]);
            }
            return arr;
        }

        let d = toTwoDimension(distance, height);
        //console.log(d);

        // 绘制高程走势图
        that._dom1.style.display = "block";
        //console.log(that._myChart);

        let opt = {
            width: 560,
            height: 180
        };

        // 使用Echart等图表工具可视化
        if (that._myChart == null) {
            that._myChart = echarts.init(that._dom1, "macaroni", opt);

            that.initChart(d, false);
        } else {
            that.initChart(d, true);
        }
    });
};

ProfileAnalysis.prototype.initChart = function(height, isMerge) {
    let option = {
        title: {
            text: "海拔走势图",
            left: "42%",
            top: "5%"
        },
        xAxis: [
            {
                type: "value",
                boundaryGap: false,
                name: "距离/m",
                axisLabel: {
                    show: true,
                    textStyle: {
                        color: "#ffffff"
                    }
                },
                nameTextStyle: {
                    color: "white",
                    fontSize: 14,
                    padding: -10
                }
            }
        ],
        yAxis: [
            {
                type: "value",
                name: "高度/m",
                scale: true,
                axisLabel: {
                    show: true,
                    textStyle: {
                        color: "#ffffff"
                    }
                },
                nameTextStyle: {
                    color: "white",
                    fontSize: 14,
                    padding: -10
                }
            }
        ],
        series: [
            {
                name: "海拔走势图",
                nameTextStyle: {
                    color: "white",
                    fontSize: 140
                    // padding: -33
                },
                type: "line",
                stack: "总量",
                areaStyle: { normal: {} },
                data: height,
                symbol: "none"
            }
        ]
    };
    this._myChart.setOption(option, isMerge);
};

ProfileAnalysis.prototype.addPoint = function(cartesian3) {


    var pt = this._viewer.entities.add(
        new Cesium.Entity({
            position: cartesian3,
            point: {
                color: Cesium.Color.SKYBLUE,
                pixelSize: 10,
                outlineColor: Cesium.Color.YELLOW,
                outlineWidth: 3
            }
        })
    );
    this.objtoremove.push(pt)
    return pt;
};

ProfileAnalysis.prototype.drawLine = function() {
    let that = this;

    var line = this._viewer.entities.add(
        new Cesium.Entity({
            polyline: {
                positions: new Cesium.CallbackProperty(() => that._linePositions, false),
                show: true,
                distanceDisplayCondition: Number.POSITIVE_INFINITY,
                material: Cesium.Color.YELLOW,
                width: 3,
                clampToGround: true
            }
        })
    );
    this.objtoremove.push(line);
    return line;
};

/**
 * 从屏幕位置得到 Cartesian3
 * @param position windowPosition
 * @param noPickEntityArray
 * @returns {null|*}
 * @private
 */
ProfileAnalysis.prototype._getCartesian3FromPosition = function(position, ...noPickEntityArray) {
    let that = this;

    let picks = this._viewer.scene.drillPick(position);
    this._viewer.render();

    let getOnModel = false;
    let cartesian3 = null;

    if (this._viewer.scene.pickPositionSupported) {
        for (let i = 0; i < picks.length; i++) {
            let pickedObject = picks[i];
            for (let j = 0; j < noPickEntityArray.length; j++) {
                let noPickEntity = noPickEntityArray[j];
                if (that._hasPickedModel(pickedObject, noPickEntity)) {
                    getOnModel = true;
                }
            }
        }
    }

    if (getOnModel) {
        cartesian3 = this._viewer.scene.pickPosition(position);
    } else {
        let ray = this._viewer.camera.getPickRay(position);
        if (Objects.isNull(ray)) {
            return null;
        }
        cartesian3 = this._viewer.scene.globe.pick(ray, this._viewer.scene);
    }
    return cartesian3;
};

ProfileAnalysis.prototype.stop = function() {
    let that = this;
    that._dom1.style.display = "none";
    ProfileAnalysis._HANDLER.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
    this._stopped = true;
};

ProfileAnalysis.prototype.destroyAll = function() {
    let that = this;
    that._dom1.style.display = "none";
    //that._viewer.entities.removeAll();

    for(var i = 0; i != that.objtoremove.length; ++i)
    {
        that._viewer.entities.remove(that.objtoremove[i]);
    }
    that.objtoremove = [];
    ProfileAnalysis.MEASURERS = [];
};

export default ProfileAnalysis;
